package com.ib.review.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class RedisUtil {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public Boolean contains(String key) {
        return stringRedisTemplate.hasKey(key);
    }

    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    /**
     * redis设置字符串，增加超时时间设置
     *
     * @param key   主键
     * @param value 值
     * @param time  时间
     * @param unit  单位
     */
    public void setex(String key, String value, long time, TimeUnit unit) {
        stringRedisTemplate.opsForValue().set(key, value, time, unit);
    }

    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    public Integer append(String key, String value) {
        return stringRedisTemplate.opsForValue().append(key, value);
    }

    public void appendAndExpire(String key, String value, long time) {
        stringRedisTemplate.opsForValue().append(key, value);
        expire(key, time, TimeUnit.MINUTES);
    }

    public Boolean expire(String key, long value, TimeUnit unit) {
        return stringRedisTemplate.expire(key, value, unit);
    }

    public void hset(String key, String hashKey, Object hashValue) {
        stringRedisTemplate.opsForHash().put(key, hashKey, hashValue);
    }

    public void hset(String key, String hashKey, Object hashValue, Long time, TimeUnit unit) {
        stringRedisTemplate.opsForHash().put(key, hashKey, hashValue);
        if (Objects.nonNull(time)) {
            expire(key, time, unit);
        }
    }

    public boolean checkHset(String key, String hashKey) {
        return stringRedisTemplate.opsForHash().hasKey(key, hashKey);
    }

    public String hget(String key, String hashKey) {
        Object obj = stringRedisTemplate.opsForHash().get(key, hashKey);
        if (Objects.nonNull(obj)) {
            return String.valueOf(obj);
        } else {
            return null;
        }
    }

    public void delete(String key) {
        stringRedisTemplate.delete(key);
    }

    public void deleteKeysByPrefix(String prefix) {
        stringRedisTemplate.execute((RedisCallback<Object>) connection -> {
            Set<String> keys = stringRedisTemplate.keys(prefix + "*");
            if (ObjectUtils.isNotEmpty(keys)) {
                byte[][] keyBytes = new byte[keys.size()][];
                int index = 0;
                for (String key : keys) {
                    keyBytes[index++] = key.getBytes();
                }
                connection.del(keyBytes);
            }
            return null;
        }, true);
    }

    public void deleteByPrefix(String prefix) {
        Set<String> keys = stringRedisTemplate.keys(prefix + "*");
        if (ObjectUtils.isNotEmpty(keys)) {
            stringRedisTemplate.delete(keys);
        }
    }
}
